package com.cityguardian.cityguardianapp;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Document;

import com.cityguardian.model.Alerta;
import com.cityguardian.model.Entidad;
import com.cityguardian.model.Usuario;
import com.cityguardian.threads.AsyncTaskMarkers;
import com.cityguardian.utils.GMapV2Direction;
import com.cityguardian.utils.MyLocationListener;
import com.cityguardian.utils.Utils;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBarActivity;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;

public class MapActivity extends ActionBarActivity {
	
	public Usuario usuario;
	public Usuario tercero;
	private	double latitud;
	private double longitud;
	private LocationManager lm;
	public GoogleMap mapa;
	private Marker posicionActual;
	public List<Alerta> listaAlerta = new ArrayList<Alerta>();
	private ArrayList<Entidad> entidades;
	private Entidad entidad;
	//private static final String EXTRA_MESSAGE = "com.cityguardian.cityguardian.mapMessage";
	@SuppressWarnings("unchecked")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_map);
		// Show the Up button in the action bar.
		setupActionBar();
		
		Intent intent = getIntent();
		Usuario usuario = (Usuario) intent.getSerializableExtra("Usuario");
		Alerta alerta = (Alerta) intent.getSerializableExtra("Alerta");
		tercero = (Usuario) intent.getSerializableExtra("Tercero");
		entidades = (ArrayList<Entidad>) intent.getSerializableExtra("Entidades");
		entidad = (Entidad) intent.getSerializableExtra("Entidad");
		String busqueda = (String) intent.getStringExtra("Busqueda");
		if (usuario!=null){
			this.usuario=usuario;
			Toast.makeText(getApplicationContext(), 
					"Bienvenido a City Guardian", Toast.LENGTH_LONG).show();
		}else{
			Toast.makeText(getApplicationContext(), 
					"Problemas con la data recibida", Toast.LENGTH_LONG).show();
		}
		
		mapa = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();
		
		LocationListener locationListener = new MyLocationListener(this);
		lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 35000, 10, locationListener);
		
		Location lastKnownLocation = lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
		if (lastKnownLocation != null) {
			latitud = lastKnownLocation.getLatitude();
			longitud = lastKnownLocation.getLongitude();
		}
		LatLng ubicacion = new LatLng(latitud, longitud);
		CameraPosition camPos = new CameraPosition.Builder()
        .target(ubicacion)   //Centramos el mapa en mi ubicacion
        .zoom(16)         //Establecemos el zoom en 16
        .build();
 
		CameraUpdate camUpd3 =
		    CameraUpdateFactory.newCameraPosition(camPos);
		 
		mapa.animateCamera(camUpd3);
		
		Log.d("mapActivity", "onCreate");
		
		posicionActual = mapa.addMarker(new MarkerOptions()
        .position(ubicacion)
        .title("posicionActual")
        .snippet("Japicoop corazon")
        .icon(BitmapDescriptorFactory
            .fromResource(R.drawable.circle_blue)));
		
		mapa.setOnMarkerClickListener(new OnMarkerClickListener()
        {

            @Override
            public boolean onMarkerClick(Marker marker) {
            	callAlertDetail(marker);
				return true;
            }

        });
		
		if (alerta!=null){
			new AsyncTaskDibujarRuta(ubicacion, new LatLng(
					Double.valueOf(alerta.getPosicionY()),
					Double.valueOf(alerta.getPosicionX()))).execute();
			//HEEEERRRRRREEEEEEEEEEEEEE
			/*drawDirections(ubicacion, new LatLng(
					Double.valueOf(alerta.getPosicionY()),
					Double.valueOf(alerta.getPosicionX())));*/			
			listaAlerta.add(alerta);
			Marker marker=mapa.addMarker(new MarkerOptions()
	        .position(new LatLng(Double.parseDouble(alerta.getPosicionY()), (Double.parseDouble(alerta.getPosicionX()))))
	        .title(alerta.getIdAlerta())
	        .snippet("alerta")
	        .icon(BitmapDescriptorFactory
	            .fromResource(R.drawable.pin_red)));
			Log.d("Alerta", marker.getTitle());
		}
		
		if (entidades!=null){
			
			int pin = 0;
			if(busqueda.equals("Hospital")){
				pin = R.drawable.hospital;
			}else if (busqueda.equals("Comisaria")){
				pin = R.drawable.policeman;
			}else if (busqueda.equals("Bomberos")){
				pin = R.drawable.industry;
			}else if (busqueda.equals("Municipalidad")){
				pin = R.drawable.receptionist;
			}else if (busqueda.equals("Clinica")){
				pin = R.drawable.hospital2;
			}
			
			for(Entidad entidad:entidades){				
				Marker marker=mapa.addMarker(new MarkerOptions()
		        .position(new LatLng(Double.parseDouble(entidad.getLatitud()), (Double.parseDouble(entidad.getLongitud()))))
		        .title(entidad.getId())
		        .snippet("entidad")
		        .icon(BitmapDescriptorFactory
		            .fromResource(pin)));
				Log.d("Entidad", marker.getTitle());
			}
		}
		
		if (entidad!=null){
			new AsyncTaskDibujarRuta(ubicacion, new LatLng(
					Double.valueOf(entidad.getLatitud()),
					Double.valueOf(entidad.getLongitud()))).execute();
			//HEREEEEEEEEE
			/*drawDirections(ubicacion, new LatLng(
					Double.valueOf(entidad.getLatitud()),
					Double.valueOf(entidad.getLongitud())));	*/		
			int pin = 0;
			if(entidad.getTipo().equals("Hospital")){
				pin = R.drawable.hospital;
			}else if (entidad.getTipo().equals("Comisaria")){
				pin = R.drawable.policeman;
			}else if (entidad.getTipo().equals("Bomberos")){
				pin = R.drawable.industry;
			}else if (entidad.getTipo().equals("Municipalidad")){
				pin = R.drawable.receptionist;
			}else if (entidad.getTipo().equals("Clinica")){
				pin = R.drawable.hospital2;
			}
			
			Marker marker=mapa.addMarker(new MarkerOptions()
	        .position(new LatLng(Double.parseDouble(entidad.getLatitud()), (Double.parseDouble(entidad.getLongitud()))))
	        .title(entidad.getId())
	        .snippet("entidad")
	        .icon(BitmapDescriptorFactory
	            .fromResource(pin)));
			Log.d("Entidad", marker.getTitle());
			entidades = new ArrayList<Entidad>();
			entidades.add(entidad);
		}
	}

	protected void callAlertDetail(Marker marker) {
		if (marker.getSnippet().equals("entidad")){
			Entidad entBuscada=null;
			for (Entidad entidad:entidades){
				if (entidad.getId().equals(marker.getTitle())){
					entBuscada=entidad;
					break;
				}
			}
			Intent intent = new Intent(this, EntityDetailActivity.class);
			intent.putExtra("Entidad", entBuscada);
			intent.putExtra("Posicion", new LatLng(latitud, longitud));
			intent.putExtra("Usuario", usuario);
			startActivity(intent);
			return;
		}
		
		if (!marker.equals(posicionActual)){
			Alerta buscada = null;
			for (Alerta alerta:listaAlerta){
				if (alerta.getIdAlerta().equals(marker.getTitle())){
					buscada=alerta;
					break;
				}
			}
			Intent intent = new Intent(this, AlertDetailActivity.class);
			intent.putExtra("Alerta", buscada);
			intent.putExtra("Usuario", usuario);
			if (!buscada.getIdUsuario().equals(usuario.getIdUsuario())){
				if (tercero!=null){
					intent.putExtra("Tercero", tercero);
				}else{
					tercero = Utils.getUsuario(buscada.getIdUsuario());
					intent.putExtra("Tercero", tercero);
				}
				startActivity(intent);
				return;
			}
			startActivity(intent);
			return;
		}
		
	}

	/**
	 * Set up the {@link android.app.ActionBar}, if the API is available.
	 */
	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	private void setupActionBar() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
			getActionBar().setDisplayHomeAsUpEnabled(true);
		}
		else {
		    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.map, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
			case android.R.id.home:
				NavUtils.navigateUpFromSameTask(this);
				return true;
            case R.id.action_button:
                sendUserForFillActivity();
                return true;
            case R.id.number_button:
            	showSearch();
            	return true;
            case R.id.action_search:
            	showSearch();
            	return true;
		}
		return super.onOptionsItemSelected(item);
	}

	private void sendUserForFillActivity() {
		Intent intent = new Intent(this, FillAlertActivity.class);
		
		//String distrito = Utils.getCiudad(latitud, longitud, this);
		intent.putExtra("Usuario", this.usuario);
		intent.putExtra("Latitud", latitud);
		intent.putExtra("Longitud", longitud);
		//intent.putExtra("Distrito", distrito);
		
    	startActivity(intent);
	}
	
	public void showAlertList() {
		Utils.getCiudad(latitud, longitud, this);
//		Location lastKnownLocation = lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
//		//Double latitud = null,longitud = null;
//		if (lastKnownLocation != null) {
//			latitud = lastKnownLocation.getLatitude();
//			longitud = lastKnownLocation.getLongitude();
//		}				
//		String cityName = null;
//        Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
//        List<Address> addresses;
//        try {
//            addresses = gcd.getFromLocation(latitud,longitud, 1);
//            if (addresses.size() > 0)
//                System.out.println(addresses.get(0).getLocality());
//            cityName = addresses.get(0).getLocality();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        String s = longitud + "\n" + latitud + "\n\nMy Current City is: "
//            + cityName;
//		
//		Toast.makeText(getApplicationContext(),s, Toast.LENGTH_LONG).show();
		
//		Intent intent = new Intent(this, AlertList2Activity.class);
//		startActivity(intent);
		
		
//		LatLng fromPosition = new LatLng(-12.0734292,-77.082157766);
//		LatLng toPosition = new LatLng(-12.00799410,-77.10278815);

		
	}
	
	private void showSearch(){
		Location lastKnownLocation = lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
		if (lastKnownLocation != null) {
			latitud = lastKnownLocation.getLatitude();
			longitud = lastKnownLocation.getLongitude();
		}
		Intent intent = new Intent(this, SearchActivity.class);
		intent.putExtra("Usuario", usuario);
		intent.putExtra("Posicion", new LatLng(latitud, longitud));
		startActivity(intent);
	}
	
	public void showAlertDetail(View view){
		Intent intent = new Intent(this, AlertDetailActivity.class);
		startActivity(intent);
	}
	
	@Override
	public void onStart(){
		super.onStart();
		Log.d("MapActivity","OnStart");
	}
	
	@Override
	public void onResume(){
		super.onResume();
		Log.d("MapActivity","OnResume");
		addMarkers();
	}
	
	private void addMarkers(){
		LatLngBounds bounds = mapa.getProjection().getVisibleRegion().latLngBounds;
    	if (Utils.haveNetworkConnection(this)){
    		AsyncTaskMarkers thread = new AsyncTaskMarkers(this);
    		//LatLng ubicacion = new LatLng(latitud, longitud);
    		thread.execute(bounds);
		}
		else{
			Toast.makeText(getBaseContext(), 
					"Intente nuevamente. No Hay Conexion a Internet!", Toast.LENGTH_LONG).show();
		}
		
	}
	
	private class AsyncTaskDibujarRuta extends AsyncTask<Integer, Double, PolylineOptions>{
		LatLng fromPosition;
		LatLng toPosition;
		
		public AsyncTaskDibujarRuta(LatLng fromP, LatLng toP){
			fromPosition=fromP;
			toPosition=toP;
		}
		
		protected void onPostExecute(PolylineOptions rectLine) {
	    
			mapa.addPolyline(rectLine);
	    }
		
		@Override
		protected PolylineOptions doInBackground(Integer... params) {
			Log.d("DIRECCIONES","MAPITA");
			GMapV2Direction md = new GMapV2Direction();

			Document doc = md.getDocument(fromPosition, toPosition, GMapV2Direction.MODE_DRIVING);
			if (doc==null) Log.d("mapa","nulo!");
			ArrayList<LatLng> directionPoint = md.getDirection(doc);
			PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED);

			for(int i = 0 ; i < directionPoint.size() ; i++) {          
				rectLine.add(directionPoint.get(i));
			}

			return rectLine;
		}
		
	
	}
	
	
	public void drawDirections(final LatLng fromPosition, final LatLng toPosition){
		Log.d("DIRECCIONES","MAPITA");
		
		this.runOnUiThread(new Runnable() {
			
			@Override
			public void run() {
				GMapV2Direction md = new GMapV2Direction();

				Document doc = md.getDocument(fromPosition, toPosition, GMapV2Direction.MODE_DRIVING);
				if (doc==null) Log.d("mapa","nulo!");
				ArrayList<LatLng> directionPoint = md.getDirection(doc);
				PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED);

				for(int i = 0 ; i < directionPoint.size() ; i++) {          
					rectLine.add(directionPoint.get(i));
				}

				mapa.addPolyline(rectLine);
				return;				
			}
		});
	}
}
